package rbac.service.collection;

import rbac.domain.dto.BaseDto;
import rbac.domain.entity.BaseEntity;
import rbac.domain.vo.BaseVo;
import rbac.domain.vo.Result;
import rbac.service.IBaseService;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 基于容器存储的业务层基类
 */

abstract class BaseService<Entity extends BaseEntity,
        Dto extends BaseDto,
        Vo extends BaseVo> implements IBaseService<Entity, Dto> {

    /**
     * 实体对象存储容器
     *
     * 以ID值为key，以实体对象为value
     * HashMap是⼀种常⽤的Map实现, 提供了快速的查找和插⼊操作
     */
    Map<Integer, Entity> data = new HashMap<>();

    int idCounter = 1;

    Vo[] temp;

    @Override
    public boolean existsById(int id){
        return data.containsKey(id); // 判断Map中是否包含指定的ID，时间复杂度为O(1)
    }

    @Override
    public Entity findById(int id) {
        if (existsById(id)) {
            return data.get(id); // 根据ID获取对应的实体对象
        }
        return null;
    }

    abstract Vo convertToVo(Entity entity);


    /**
     * {@inheritDoc}
     * <p>
     *     该⽅法通过java 8的d流式操作（stream）从数据存储`Map`中获取所有值，
     *     并使⽤{@link #convertToVo(BaseEntity)}⽅法将每个数据项转换为对应的VO对象。
     *     然后将转换后的VO对象列表转换为数组，并封装到⼀个{@link Result}对象中返回
     * </p>
     */
    @Override
    public Result list(){
        List<Vo> list = data.values().stream().map(this::convertToVo).toList();
        return Result.success(" 查询成功",list.toArray(temp));
        // list.toArray(temp)： 将List转换为数组，这⾥使⽤temp数组作为参数，如果temp数组的⼤⼩⾜够，则会使⽤该数组存储元素；否则会创建⼀个新的数组。
    }

    abstract Entity createEntity(Dto dto, int id);

    @Override
    public Result create(Dto dto){ // 用dto数据传输对象来传入参数

        Entity entity = createEntity(dto, idCounter++);

        data.put(entity.getId(), entity);

        return Result.success(" 创建成功", null);
    }

    abstract void updateEntity(Dto dto, Entity entity);

    @Override
    public Result update(Dto dto, int id){
        if (!existsById(id)){
            return Result.failure("更新失败，不存在该数据");
        }

        Entity entity = data.get(id); // 获取指定ID 的实体对象

        updateEntity(dto, entity);

        return Result.success(" 更新成功", null);
    }


}

